<template>
  <div class="myTableSearch">
    <!-- <myTitleName style="margin-bottom: 16px;" :titleName="titleName" v-if="titleName">
      <template slot="titleRight" v-if="$slots.tableTitleRight">
        <slot name="tableTitleRight"></slot>
      </template>
      <div class="screen" v-if="formData.length > 4" @click="isScreen = !isScreen">
        筛选
        <img v-if="isScreen" src="@/assets/images/icon/arrowUp.png" alt="">
        <img v-else src="@/assets/images/icon/arrowDown.png" alt="">
      </div>
    </myTitleName> -->
    <div class="lump" style="top:0;left:0;"></div>
    <div class="lump" style="top:0;right:0;"></div>
    <div class="lump" style="bottom:0;left:0;"></div>
    <div class="lump" style="bottom:0;right:0;"></div>
    <!-- <div class="tableSearchTitle" v-if="titleName">
      <span>{{titleName}}</span>
      <template slot="titleRight" v-if="$slots.tableTitleRight">
        <slot name="tableTitleRight"></slot>
      </template>
    </div> -->
    <div class="tableCentent">
      <el-form class="search" label-suffix="">
        <div id="searchCon" class="searchCon" ref="searchCon" style="overflow: hidden;"
          :style="{ maxHeight: isScreen&&false ? '56px' : 'max-content' }">
          <el-row :gutter="21" style="flex-wrap: no-wrap;" type="flex" v-if="formData.length">
            <el-col :key="index" :xl='colXl' :lg="colLg" :md="12" :sm="24" v-for="(item, index) in formData">
              <!-- 输入框 -->
              <el-form-item :label="item.label" :label-width="item.labelWidth||labelWidth||setLabelNameSize(item.label)" v-if="item.type == 'input'">
                <el-input :placeholder="item.placeholder?item.placeholder:'请输入' + item.label" clearable
                  v-model="item.value" :style="{width:item.width}"></el-input>
              </el-form-item>
              <!-- 下拉选择器 -->
              <el-form-item :label="item.label" :label-width="item.labelWidth||labelWidth||setLabelNameSize(item.label)" v-if="item.type == 'select'">
                <el-select  :disabled="item.disabled||false" :placeholder="'请选择' + item.label" clearable :style="{width:item.width}"
                  v-model="item.value" @change="(e)=>item.change && item.change(e,formData)">
                  <el-option :key="idx" :label="(item.optionLabel ? ele[item.optionLabel] : ele.dictLabel)"
                    :value="item.optionValue ? ele[item.optionValue] : ele.dictValue"
                    v-for="(ele, idx) in item.data"></el-option>
                </el-select>
              </el-form-item>
              <el-form-item :label="item.label" :label-width="item.labelWidth||labelWidth||setLabelNameSize(item.label)" v-if="item.type == 'date'">
                <el-date-picker v-model="item.value" placeholder="选择日期" style="width: 100%;"
                  :value-format="item.format || 'yyyy-MM-dd'">
                </el-date-picker>
              </el-form-item>
              <!-- 日期范围选择器 -->
              <el-form-item :label="item.label" :label-width="item.labelWidth||labelWidth||setLabelNameSize(item.label)" v-if="item.type == 'daterange'">
                <el-date-picker end-placeholder="结束日期" range-separator="~" start-placeholder="开始日期" style="width: 100%;"
                  :value-format="item.format || 'yyyy-MM-dd'" type="daterange" v-model="item.value"></el-date-picker>
              </el-form-item>
              <!-- 日期时间范围选择器 -->
              <el-form-item :label="item.label" :label-width="item.labelWidth||labelWidth||setLabelNameSize(item.label)"
                v-if="item.type == 'datetimerange'">
                <el-date-picker end-placeholder="结束日期" range-separator="~" start-placeholder="开始日期" style="width: 100%;"
                  type="datetimerange" v-model="item.value"></el-date-picker>
              </el-form-item>
              <!-- 年选择器 -->
              <el-form-item :label="item.label" :label-width="item.labelWidth||labelWidth||setLabelNameSize(item.label)" v-if="item.type == 'year'">
                <el-date-picker placeholder="选择年" :value-format="item.format || 'yyyy'" style="width: 100%;" type="year"
                  v-model="item.value">
                </el-date-picker>
              </el-form-item>
              <!-- 月选择器 -->
              <el-form-item :label="item.label" :label-width="item.labelWidth||labelWidth||setLabelNameSize(item.label)" v-if="item.type == 'month'">
                <el-date-picker v-model="item.value" :value-format="item.format || 'yyyy-MM'" style="width: 100%;"
                  type="month" placeholder="选择月"></el-date-picker>
              </el-form-item>

              <!--   插槽   -->
              <el-form-item :label="item.label" :label-width="item.labelWidth||labelWidth||setLabelNameSize(item.label)" v-if="item.type === 'slot'">
                <slot :item="item" :name="item.slotName" :row="item" />
              </el-form-item>

              <!--   样式兼容插槽   -->
              <el-form-item :label="item.label" :label-width="item.labelWidth||labelWidth||setLabelNameSize(item.label)" class="custom-label"
                v-if="item.type === 'blockSlot'">
                <slot :item="item" :name="item.slotName" :row="item" />
              </el-form-item>
            </el-col>

            <el-col :lg="searchColLg" :md="12" :sm="24"
              style="flex:1;"
              :class="titleName && formData.length > 4 && false ? 'isScreenSearchOperate' : 'searchOperate'">
              <el-form-item label-width="0px">
                <div class="searchBtnBox">
                  <div class="searchBtn" @click="handleSearch">
                    <img src="@/assets/images/gzq/search2.png" alt="">
                    查询</div>
                  <div class="resetBtn ml-1" @click="searchReset">重置</div>
                </div>
              </el-form-item>
            </el-col>
          </el-row>
        </div>
      </el-form>

      <!-- 自定义搜索 -->
      <slot name="diySearch"></slot>
      <div class="line" v-if="formData.length && isTool"></div>
      <div class="tableTool" v-if="formData.length && isTool">
        <slot name="tool"></slot>
        <div v-if="!$slots.tool"></div>
        <div class="toolIcon" v-if="isShowToolIcon&&false">
          <img @click="handleSearch" alt="" src="@/assets/images/icon/searchTool.png">
          <img @click="searchReset" alt="" src="@/assets/images/icon/resetTool.png">
          <img alt="" src="@/assets/images/icon/timeTool.png">
          <img alt="" src="@/assets/images/icon/arrowUpTool.png">
          <!-- <el-popover>
            <img alt="" slot="reference" src="@/assets/images/icon/tool.png" style="display: list-item;">
            <el-checkbox-group class="tableShowlabel" v-model="tableShowlabel">
              <el-checkbox :disabled="tableShowlabel.length === 1 && ele.prop === tableShowlabel[0].prop" :key="idx"
                :label="ele" class="tableShowlabelItem" v-for="(ele, idx) in tableLabel">{{ ele.label }}
              </el-checkbox>
            </el-checkbox-group>
          </el-popover> -->
        </div>
      </div>

      <div class="table">
        <el-table :cell-style="cellStyle" :data="tableData" :header-cell-style="headerStyle" :row-class-name="rowClassName"
          @row-click="rowClick" @selection-change="tableSelectChange" ref="table" :row-key="rowKey" style="width: 100%"
          @cell-click="cellClick"
          :tree-props="treeProps"
          :default-expand-all="defaultExpandAll"
          v-loading="loading"
          element-loading-text="拼命加载中"
          element-loading-background="rgba(0, 0, 0, 0.7)"
          border
          >
          <el-table-column type="selection" v-if="isSelection" reserve-selection align="center"
            width="55"></el-table-column>
          <el-table-column :index="typeIndex" align="center" label="序号" type="index" v-if="isIndex"
            width="80"></el-table-column>
          <template v-for="(item, index) in tableShowlabel">
            <!-- 插槽格式化table -->
            <el-table-column :align="item.align || 'center'" :key="index" :label="item.label" :prop="item.prop"
              :show-overflow-tooltip="item.isTooltip || true" :min-width="item.minWidth" :width="item.width" v-if="!item.formatter">
              <template slot-scope="scope">
                <slot :label="item" :name="item.prop" :row="scope.row" :rowIndex="scope.$index" ref="slot">
                  {{
                    scope.row[item.prop] === null || scope.row[item.prop] === undefined || scope.row[item.prop] === ''
                    ? '-' : scope.row[item.prop] }}
                </slot>
              </template>

              <!-- 二级头部 -->
              <template v-if="item.children">
                <el-table-column v-for="(child, childIndex) in item.children || []" :align="child.align || 'center'"
                  :key="childIndex" :label="child.label" :prop="child.prop" :show-overflow-tooltip="child.isTooltip || true"
                  :width="child.width">
                  <template slot-scope="scope">
                    <slot :label="child" :name="child.prop" :row="scope.row" :rowIndex="scope.$index" ref="slot">
                      {{
                        scope.row[child.prop] === null || scope.row[child.prop] === undefined || scope.row[child.prop] === ''
                        ? '-' : scope.row[child.prop] }}
                    </slot>
                  </template>
                </el-table-column>
              </template>
            </el-table-column>
            <!-- formatter格式化table -->
            <el-table-column :align="item.align || 'center'" :formatter="item.formatter" :key="index" :label="item.label"
              :min-width="item.minWidth" :prop="item.prop" :show-overflow-tooltip="item.isTooltip || true"
               v-else>
            </el-table-column>
          </template>

          <el-table-column :width="operateWidth" align="center" fixed="right" label="操作" v-if="isOperate">
            <template slot-scope="scope">
              <slot :row="scope.row" name="operate"></slot>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!-- 分页 -->
      <div class="pagination" v-if="total > queryParams.pageSize && isPagination">
        <el-pagination :current-page="queryParams.pageNum" :layout="'total,prev,pager,next'"
          :page-size="queryParams.pageSize" :page-sizes="queryParams.pageSizes" :total="total"
          @current-change="handleCurrentChange" @size-change="handleSizeChange" background hide-on-single-page />
      </div>

      <slot name="pagination" v-if="($slots.pagination && Array.isArray($slots.pagination) && $slots.pagination.length)"></slot>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    // 头部名称
    titleName: {
      type: String,
      default: ''
    },
    //请求接口
    queryFn: {
      // type: Function,
      // required: true,
    },
    // 数据选择
    tableSelectChange: {
      default: Function
    },
    // 搜索自定义宽度
    labelWidth: {
      type: [String, Number],
      default:0,
    },
    // 搜索宽度
    colLg: {
      type: [String, Number],
      default: 6
      // default: 5
    },
    colXl: {
      type: [String, Number],
      default: 6
      // default: 5
    },
    searchColLg: {
      type: [String, Number],
      default: 6
      // default: 4
    },
    // 操作区域
    isTool: {
      type: Boolean,
      default: true
    },
    isShowToolIcon: {
      type: Boolean,
      default: true
    },
    //table操作
    isOperate: {
      type: Boolean,
      default: false
    },
    //table操作宽度
    operateWidth: {
      type: [String, Number],
      default: '120'
    },
    //序号
    isIndex: {
      type: Boolean,
      default: true
    },
    //多选
    isSelection: {
      type: Boolean,
      default: false
    },
    rowKey: {
      type: [String, Function],
      default: 'id'
    },
    treeProps:{
      type: Object,
      default: () => {
        return {
          children: 'children',
        }
      }
    },
    defaultExpandAll: {
      type: Boolean,
      default: false
    },
    formData: {
      type: Array,
      default: () => []
    },
    tableLabel: {
      type: Array,
      default: () => []
    },
    // 是否展示分页
    isPagination: {
      type: Boolean,
      default: true
    },
    rowClassName: {
      default: null
    },
    diyTableData: {
      default: () => {
        return []
      }
    },
    // 分页相关参数
    pageParams: {
      type: Object,
      default: () => {
        return {
          pageNum: 1,//当前页
          pageSize: 10,//一页数量
          pageSizes: [10, 20, 50, 100]
        }
      }
    },
  },
  data() {
    return {
      loading:false,//列表接口加载状态
      // 搜索折叠展开
      isScreen: false,
      tableShowlabel: [],
      total: 0,//总数
      tableData: [],
      form: {},
      element: {},
      queryParams:{},//接口请求参数
    }
  },
  watch: {
    titleName: {
      handler(val) {
        if (val && this.formData.length > 4) {//有标题显示筛选
          this.isScreen = true;
        } else {
          this.isScreen = false;
        }
      },
      immediate: true,
    },
    diyTableData: {
      handler(val) {
        // if (val && val.length > 0) {
          this.initTableData({}, false)
        // }
      },
      immediate: true,
      deep: true,
    },
    tableLabel: {
      handler: function (val) {
        // console.log('tableLabel', val)
        // console.log('tableLabel', this.tableLabel)
        this.tableShowlabel = val
      },
      immediate: true,
      deep: true,
    },
    queryFn: {
      handler(val) {
        if (val) {
          this.initTableData({}, false)
        }
      }
    },
    pageParams:{
      handler(newValue) {
        this.queryParams = {
          ...this.queryParams,
          ...newValue,
        }
      },
      immediate: true,
      deep: true,
    }
  },
  created() {
    // this.tableShowlabel = this.tableLabel;
    // 初始化搜索
    this.initFormData()
    //初始化table数据
    this.initTableData({}, false)
  },
  methods: {
    //table数据
    initTableData(param, reset = false) {
      this.loading = true;
      this.queryParams.query = param || {}
      // 格式化搜索字段
      this.$emit('recombinationData', param, (newParam) => {
        if(newParam !== undefined && newParam.recombinationDataType == 'queryParams'){
          this.queryParams = newParam;
          delete this.queryParams.recombinationDataType;
        }else if (newParam !== undefined){
          this.queryParams.query = newParam
        }
      }, reset)
      if (this.queryFn) {
        this.queryFn(this.queryParams).then(res => {
          if (res && res.code == 200 && res.data) {
            this.tableData = res.data.rows?res.data.rows:res.data;
            this.total = Number(res.data.total)
            this.$emit('successQuery', res.data,(data)=>{
              this.tableData = data;
            })
            this.loading = false;
          }
        }).catch(err => {
          console.log('请求出错', err)
          this.loading = false;
        })
      } else {
        if(this.isPagination){
          this.total = this.diyTableData.length
          this.tableData = this.diyTableData.slice((this.queryParams.pageNum - 1) * this.queryParams.pageSize, this.queryParams.pageNum * this.queryParams.pageSize)
        }else{
          this.tableData = this.diyTableData;
        }
        this.loading = false;
      }
    },
    handleSizeChange(pageSize) {
      this.queryParams.pageSize = pageSize
      this.initTableData({}, false)
    },
    //分页事件
    handleCurrentChange(pageNum) {
      this.queryParams.pageNum = pageNum
      this.initTableData({}, false)
    },
    rowClick(row) {
      this.$emit('rowClick', row)
    },
    cellClick(row, column, cell, event) {
      this.$emit('cellClick', row, column, cell, event)
    },
    reload() {// 重新加载
      this.handleSearch()
    },

    // 查询数据
    handleSearch(reset) {
      const param = this.assembleSearchData();
      // this.$emit('initTableData', param, reset)
      this.initTableData(param, reset)
    },

    // 重置数据
    // isRequire为true 赋值value
    searchReset() {
      this.form.map((item, idx) => {
        switch (item.type) {
          case 'radio':
          case 'input':
          case 'select':
          case 'blockSlot':
            item.value = ''
            break
          case 'year':
          case 'month':
          case 'date':
          case 'slot':
            item.value = ''
            break
          case 'checkbox':
            item.value = []
            break
          case 'datetimerange':
          case 'daterange':
            item.value = []
            break
        }
      })
      this.handleSearch(true)
    },

    // 组装查询/重置数据
    assembleSearchData() {
      const param = {};
      this.form.forEach(item => {
        if ((typeof item.value === 'string' && item.value) || (typeof item.value === 'number') || (typeof item.value === 'object' && item.value.length !== 0)) {
          param[item.key] = item.screen !== undefined ? item.screen(item.value) : item.value
        }
      })
      return param
    },
    //列表序号
    typeIndex(index) {
      if(this.queryParams&&this.queryParams.pageNum ){
        return index + (this.queryParams.pageNum - 1) * this.queryParams.pageSize + 1
      }else{
        return index + 1;
      }
    },
    headerStyle() {
      return 'background:#f7f8fa;color: #464D5A;font-size: 14px; height: 36px; border:1px solid #1e6fff0d;'
    },
    // 搜索宽度
    setLabelNameSize(str) {
      return `${str.length * 14 + 27}px`
    },
    // 初始化搜索form
    initFormData() {
      this.form = this.formData.map(item => {
        if (item.requestType === 'dict') {
          // 请求字典
          this.getDicts(item.dictName).then(res => {
            if (res && res.code == 200 && res.data) {
              item.data = res.data;
            }
          })
        } else if (item.requestType === 'port') {// 请求接口

        }

        this.$set(this, 'element', item)
        switch (item.type) {
          case 'radio':
          case 'input':
          case 'select':
            this.$set(this.element, 'change', item.change ? item.change : new Function())
          case 'year':
          case 'month':
          case 'date':
          case 'slot':
          case 'blockSlot':
            this.$set(this.element, 'value', item.value ? item.value : '')
            break
          case 'checkbox':
            this.$set(this.element, 'value', [])
            break
          case 'datetimerange':
          case 'daterange':
            this.$set(this.element, 'value', [])
            break
        }
        return this.element
      })
    },
    cellStyle({row, column, rowIndex}) {
      if (rowIndex % 2 == 0) {
        return 'background: #FFF!important;border:1px solid #1e6fff0d;line-height: 42px;height:42px;color: #464D5A;font-size: 14px;'
      } else {
        return 'background: #FFF!important;border:1px solid #1e6fff0d;line-height: 36px;height: 36px;color: #464D5A;font-size: 14px;'
      }
    },
  },
}
</script>

<style lang="scss" scoped>
.tableShowlabel {
  cursor: pointer;
  padding: 0 10px;
  display: flex;
  flex-direction: column;

  .tableShowlabelItem {
    padding: 5px 0px;
  }
}

.myTableSearch {
  position: relative;
  // padding: 5px;
  // border: 1.5px solid #84f0ff33;
  // border: 1.5px solid red;
  background: #fff;
  height: 100%;
  display: flex;
  flex-direction: column;
  .lump{
    position: absolute;
    width: 4px;
    height: 4px;
    //  background: #3ef4ff;
  }
  .tableSearchTitle{
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 38px;
    background: rgba(45, 112, 147, 0.5);
    color: #eafaff;
    font-size: 16px;
    padding: 0 15px;
  }
  .screen {
    margin-left: 32px;
    width: 80px;
    height: 30px;
    border-radius: 3px;
    background: rgba(24, 144, 255, 1);
    display: flex;
    align-items: center;
    justify-content: center;
    color: rgba(255, 255, 255, 1);
    font-family: OPPOSans;
    font-weight: bold;
    font-size: 12px;

    img {
      width: 24px;
      height: 24px;
    }

    cursor: pointer;
  }

  .isScreenSearchOperate {
    position: absolute;
    top: 0;
    right: 0;
  }
  .searchBtnBox{
    flex: 1;
    height: 40px;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    >div{
      cursor: pointer;
      width: 80px;
      height: 34px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: #464D5A;
      font-size: 14px;
      // padding: 8px 34px;
      border-radius: 2px;

      box-sizing: border-box;
    }

    .searchBtn{
      background: #1E6FFF;
      color: #FFFFFF;
      >img{
        width: 20px;
        height: 20px;
      }
    }
    .resetBtn{
      background: #fff;
      border: 1px solid #edf0f2;
    }
  }

  .search {
    // border-bottom: 1px solid #EDF0F2;
    // padding-bottom: 24px;
  }

  .line {
    margin: 0px 0 16px;
    width: 100%;
    height: 1px;
    background-color: #EDF0F2;
  }

  .tableTool {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 16px;


    .toolIcon {
      display: flex;
      align-items: center;

      img {
        cursor: pointer;
        padding: 8px 14px;
        box-sizing: content-box;
        width: 24px;
        height: 24px;
        border: 1px solid #113C4E;
      }
    }
  }

  .tableCentent{
    // flex: 1;
    height: calc(100% - 38px);
    display: flex;
    flex-direction: column;
    // padding:30px 30px 15px;
    .table {
      flex: 1;
      overflow: auto;
      width: 100%;
      // margin-top: 24px;
    }

    .pagination {
      display: flex;
      justify-content: end;
      margin-top: 10px;
      /deep/.el-pagination__total{
        color: #fff;
      }
      /deep/.el-pagination.is-background .btn-next,/deep/.el-pagination.is-background .btn-prev,/deep/.el-pagination.is-background .el-pager li{
        border: 1px solid #edf0f2;
        color: #464D5A;
      }
      /deep/.el-pagination.is-background .el-pager li:not(.disabled).active {
        background: #1e6fff1a;
        border: 1px solid #1e6fff;
        color: #1E6FFF;
      }
      /deep/.el-pager li:not(.disabled):hover {
        border: 1px solid #464D5A;
      }
    }
  }
}

::v-deep.el-date-editor .el-range-separator {
  width: 10%;
}

/deep/ .el-form-item__label {
  color: #464D5A;
  // font-weight: bold;
  font-size: 14px;
}

/deep/.el-input__inner{
  color: #464D5A;
  background: #FFFFFF;
  border:none;
}
/deep/.el-range-editor .el-range-input{
  background: #132C42;
}
/deep/.el-date-editor .el-range-separator{
  color: #464D5A;
}
/deep/.el-date-editor .el-range-input{
  color: #464D5A;
}

/deep/ .el-table__header-wrapper .el-table-column--selection .cell {
  padding-left: 12px !important;

}
/deep/.el-checkbox__input{

  &:hover{
    border-color: #1E6FFF;
  }
}
/deep/.el-checkbox__input.is-checked .el-checkbox__inner{
  background: #1E6FFF;
  border-color: #1E6FFF;
}
</style>
